package com.example.tccdemo.consumer;

import com.example.tccdemo.db164.dao.OrderMapper;
import com.example.tccdemo.db164.model.Order;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

import static org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
import static org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus.RECONSUME_LATER;

/**
 * @author caryguan
 * @version V1.0
 * @Package com.example.tccdemo.consumer
 * @date 2020/10/16 14:07
 */
@Component("messageListener")
//这里要注意的是,我们既然选择了autowired的方式注入实例,那么也需要实例化这个类,controller用在controller层,service用在service层
//repository用在dao层,我们这个不伦不类可以用component注解来标识,其实含义都是一样的都是注册在spring容器里
public class ChangeOrderStatus implements MessageListenerConcurrently {

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
        if (msgs == null || msgs.size() == 0) {
            return CONSUME_SUCCESS;
        }
        for (MessageExt messageExt : msgs) {
            String orderId = messageExt.getKeys();
            String message = new String(messageExt.getBody());
            System.out.println("message: " + message);
            Order order = orderMapper.selectByPrimaryKey(Integer.parseInt(orderId));
            if(order==null){
                //我们的订单查询不到,但是我们实际是支付了的,所以可以该状态为再次消费
                //这里其实有逻辑问题,按理来说,我们的订单时支付了,如果为null的话,之前支付的订单时哪里来的,这里就涉及具体的业务场景了,所以先表示一下提醒
                return RECONSUME_LATER;
            }

            try {
                order.setOrderStatus(1);
                order.setUpdateTime(new Date());
                order.setUpdateUser(0);
                orderMapper.updateByPrimaryKey(order);
            } catch (Exception e) {
                e.printStackTrace();
                //如果在更新订单的时候失败了,那么返回再次消费
                return RECONSUME_LATER;
            }
           //这里有一个逻辑漏洞,那就是我们的list是多个的话,如果第一个消费成功,第二个消费失败,那么就会返回重复消费的状态,但是我们第一个消费确实做了,所以会造成潜在的逻辑错误
            //但是这里看了源码以后最大的list值为1,只是这个值我们可以修改,如果我们不修改List长度的话,这段程序是正确的

        }
        return CONSUME_SUCCESS;
    }
}